#include "fiber.h"
#include "scheduler.h"
#include "mutex.h"
#include "chan.h"
#include "no_lock_mutex.h"

typedef no_lock_mutex mutex_t;
void *main_fiber;
mutex g_mtx;
chan<std::string> g_chan(1);
void func_text_mutex(std::string str)
{
	lock_guard mg (g_mtx);
	std::cout << str;
	std::cout << " [lock]" << std::endl;;
	std::cout << str;
	std::cout << " [unlock]" << std::endl << std::endl;;
	
}

void func_recv (std::string str)
{
	do 
	{
		auto data = g_chan.recv ();
		lock_guard mg (g_mtx);
		std::cout << "{{{{recv}}}}: " << data << " ";
		std::cout << std::endl;

	} while (1);
	
}
void func_send(std::string str)
{
	do 
	{
		g_chan.send (str);

		lock_guard mg (g_mtx);
		std::cout << "[[[[send]]]]: " << str << " ";
		std::cout << std::endl;

	} while (1);
}


int test_fiber()
{
	main_fiber = ConvertThreadToFiber(NULL);

	fiber::ptr_t f = fiber::create_fiber(func_recv, "hello world");
	f->switch_to_fiber();
	std::cout << "main" << std::endl;
	return 0;
}
int test_chan()
{
	scheduler s;
	s.append_fiber(fiber::create_fiber(func_recv, "s1 hello world1"));
	s.append_fiber(fiber::create_fiber(func_send, "s1 hello world2"));


	s.start ();


	while (s.get_fiber_size ())
	{
		std::this_thread::sleep_for(std::chrono::milliseconds(1000));
	}
	s.stop();
	return 0;
}

int test_sleep()
{
	scheduler s;
	s.append_fiber([&]{
		
		do 
		{
			
			current_fiber->sleep(1000);
			std::cout << high_resolution_clock::now().time_since_epoch().count() << std::endl;

		} while (1);
		
	});

	s.start();
	getchar();
	return 0;
}
#include "condition_variable.h"
int main()
{
	condition_variable<mutex_t> cv;
	mutex mtx;
	scheduler s;
	s.append_fiber([&]{

		do
		{
			unique_locker n_lock(mtx);
			if(cv.wait_for(n_lock , 2000) == condition_variable<mutex_t>::cv_status::no_timeout)
				std::cout << "1 " << high_resolution_clock::now().time_since_epoch().count() << std::endl;

		} while (1);

	});
	s.append_fiber([&]{

		do
		{
			unique_locker n_lock(mtx);
			cv.wait(n_lock);
			std::cout <<"2 "<< high_resolution_clock::now().time_since_epoch().count() << std::endl;

		} while (1);

	});

	s.append_fiber([&]{

		do
		{
			cv.notify_all();
			current_fiber->sleep(100);
		} while (1);

	});

	s.start();
	getchar();
	s.stop();
}